"""认证和授权管理

提供用户认证、API密钥验证和权限控制功能。
"""

import uuid
import jwt
import datetime
import hashlib
import secrets
from typing import Dict, List, Optional, Any
from utils.logger import get_logger
from utils.exceptions import AuthenticationException

logger = get_logger(__name__)

class AuthManager:
    """认证和授权管理器
    
    负责:
    1. 用户认证和会话管理
    2. API密钥生成和验证
    3. 权限控制和访问策略
    """
    
    def __init__(self, secret_key: str, admin_api_key: Optional[str] = None):
        """初始化认证管理器
        
        Args:
            secret_key: 用于JWT签名的密钥
            admin_api_key: (可选) 用于管理员的固定API密钥
        """
        self.secret_key = secret_key
        self.admin_api_key = admin_api_key
        self.users = {}  # 模拟用户数据库
        self.api_keys = {}  # 模拟API密钥存储
        self.current_user = None  # 当前认证用户
        
        # 创建默认管理员用户
        self._create_default_admin()
    
    def _create_default_admin(self):
        """创建默认管理员用户"""
        admin_id = str(uuid.uuid4())
        admin_api_key = self.admin_api_key or self._generate_api_key()
        
        self.users[admin_id] = {
            'user_id': admin_id,
            'username': 'admin',
            'password_hash': self._hash_password('admin'),  # 默认密码
            'role': 'admin',
            'permissions': ['*'],  # 所有权限
            'created_at': datetime.datetime.utcnow().isoformat()
        }
        
        self.api_keys[admin_api_key] = {
            'user_id': admin_id,
            'created_at': datetime.datetime.utcnow().isoformat(),
            'expires_at': None  # 永不过期
        }
        
        logger.info(f"Created default admin user with API key: {admin_api_key}")
    
    def _hash_password(self, password: str) -> str:
        """对密码进行哈希处理
        
        Args:
            password: 原始密码
            
        Returns:
            密码哈希值
        """
        return hashlib.sha256(password.encode()).hexdigest()
    
    def _generate_api_key(self) -> str:
        """生成随机API密钥
        
        Returns:
            API密钥
        """
        return secrets.token_hex(32)
    
    def create_user(self, user_data: Dict[str, Any]) -> Dict[str, Any]:
        """创建新用户
        
        Args:
            user_data: 用户数据，包含username、password、role等
            
        Returns:
            新创建的用户信息
            
        Raises:
            AuthenticationException: 如果用户名已存在
        """
        username = user_data.get('username')
        password = user_data.get('password')
        role = user_data.get('role', 'user')
        permissions = user_data.get('permissions', [])
        
        # 验证必要字段
        if not username or not password:
            raise AuthenticationException('Username and password are required', 'INVALID_INPUT')
        
        # 检查用户名是否已存在
        for user in self.users.values():
            if user['username'] == username:
                raise AuthenticationException(f'Username {username} already exists', 'USER_EXISTS')
        
        # 创建用户
        user_id = str(uuid.uuid4())
        api_key = self._generate_api_key()
        
        self.users[user_id] = {
            'user_id': user_id,
            'username': username,
            'password_hash': self._hash_password(password),
            'role': role,
            'permissions': permissions,
            'created_at': datetime.datetime.utcnow().isoformat()
        }
        
        self.api_keys[api_key] = {
            'user_id': user_id,
            'created_at': datetime.datetime.utcnow().isoformat(),
            'expires_at': None  # 默认永不过期
        }
        
        logger.info(f"Created new user: {username} with role: {role}")
        
        return {
            'user_id': user_id,
            'username': username,
            'api_key': api_key,
            'role': role
        }
    
    def generate_api_key(self, user_id: str, expires_in: Optional[int] = None) -> Dict[str, str]:
        """为指定用户生成新的API密钥
        
        Args:
            user_id: 用户ID
            expires_in: 过期时间（秒），None表示永不过期
            
        Returns:
            包含API密钥和过期时间的字典
            
        Raises:
            AuthenticationException: 如果用户不存在
        """
        if user_id not in self.users:
            raise AuthenticationException(f'User {user_id} not found', 'USER_NOT_FOUND')
        
        api_key = self._generate_api_key()
        created_at = datetime.datetime.utcnow()
        expires_at = None
        
        if expires_in:
            expires_at = created_at + datetime.timedelta(seconds=expires_in)
        
        self.api_keys[api_key] = {
            'user_id': user_id,
            'created_at': created_at.isoformat(),
            'expires_at': expires_at.isoformat() if expires_at else None
        }
        
        logger.info(f"Generated new API key for user: {user_id}")
        
        return {
            'api_key': api_key,
            'expires_at': expires_at.isoformat() if expires_at else None
        }
    
    def validate_api_key(self, api_key: str) -> bool:
        """验证API密钥
        
        Args:
            api_key: API密钥
            
        Returns:
            如果API密钥有效则返回True，否则返回False
        """
        if api_key not in self.api_keys:
            return False
        
        key_info = self.api_keys[api_key]
        user_id = key_info['user_id']
        expires_at = key_info.get('expires_at')
        
        # 检查是否过期
        if expires_at:
            expires_at_dt = datetime.datetime.fromisoformat(expires_at)
            if expires_at_dt < datetime.datetime.utcnow():
                logger.warning(f"API key expired for user: {user_id}")
                return False
        
        # 设置当前用户
        self.current_user = self.users.get(user_id)
        
        return True
    
    def is_admin(self) -> bool:
        """检查当前用户是否为管理员
        
        Returns:
            如果当前用户是管理员则返回True，否则返回False
        """
        if not self.current_user:
            return False
        
        return self.current_user.get('role') == 'admin'
    
    def has_permission(self, permission: str) -> bool:
        """检查当前用户是否具有指定权限
        
        Args:
            permission: 权限标识符
            
        Returns:
            如果当前用户具有指定权限则返回True，否则返回False
        """
        if not self.current_user:
            return False
        
        # 管理员拥有所有权限
        if self.current_user.get('role') == 'admin':
            return True
        
        permissions = self.current_user.get('permissions', [])
        return permission in permissions or '*' in permissions
    
    def generate_token(self, user_id: str, expires_in: int = 3600) -> str:
        """生成JWT令牌
        
        Args:
            user_id: 用户ID
            expires_in: 过期时间（秒）
            
        Returns:
            JWT令牌
        """
        payload = {
            'user_id': user_id,
            'exp': datetime.datetime.utcnow() + datetime.timedelta(seconds=expires_in)
        }
        
        return jwt.encode(payload, self.secret_key, algorithm='HS256')
    
    def validate_token(self, token: str) -> Optional[Dict[str, Any]]:
        """验证JWT令牌
        
        Args:
            token: JWT令牌
            
        Returns:
            如果令牌有效，则返回用户信息，否则返回None
        """
        try:
            payload = jwt.decode(token, self.secret_key, algorithms=['HS256'])
            user_id = payload.get('user_id')
            
            if user_id in self.users:
                self.current_user = self.users[user_id]
                return self.current_user
            
            return None
        except jwt.PyJWTError as e:
            logger.warning(f"Token validation failed: {str(e)}")
            return None